home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Alles Voor Internet / Tout Pour Internet
/
alles voor internet.iso
/
MacInternet™
/
Telnet
/
NCSA
/
tn3270 2.4d7 source
/
tn3270
/
api.c
< prev
next >
Wrap
Text File
|
1992-04-17
|
31KB
|
1,312 lines
/*
* tn3270 for the Macintosh Source Code
* Brown University Computing and Information Services
* Version 2.4d7 April, 1992
* Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
* Peter John DiCamillo.
*
* Permission is granted to any individual or institution to use, copy,
* or redistribute the binary version of this software and its
* documentation provided this notice and the copyright notices are
* retained. Permission is granted to any individual or non-profit
* institution to use, copy, modify, or redistribute the source files
* of this software provided this notice and the copyright notices are
* retained. This software may not be distributed for profit, either
* in original form or in derivative works, nor can the source be
* distributed to other than an individual or a non-profit institution.
* Any individual or group interested in seeing and/or using these
* source files but who are prevented from doing so by the above
* constraints should contact Don Wolfe, Assistant Vice-President for
* Computer Systems at Brown University, (401) 863-7250, for possible
* software licensing of the source developed at Brown.
*
* Brown University and Peter John DiCamillo make no representations
* about the suitability of this software for any purpose.
*
* BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
* EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
* INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#if !defined(USEDUMP)
#include "maclib.h"
#include "termdef.h"
#include "tn3270funcs.h"
#include "globals.h"
#else
#pragma load "tn3270DumpFile"
#endif
#include "telnet.h"
#include "sppc.h"
#pragma segment api
Handle rcvMessage, sndMessage; /* handles to message buffers */
short fromrefnum; /* data for last received message */
unsigned short msgLength;
unsigned long msgId, replyId;
cnr *msgcp;
unsigned char sppc_sessname[8] = "GFTM1-1";
unsigned char ppcsessname[] = "\ptn3270 #1 session 1";
char apimsgkind; /* 0 = , 1 = SPPC */
static unsigned long apimsgid = 0;
long ppcsref; /* used by PPC instead of fromrefnum */
void apiregister(char session, cnr *cp) /* register our API */
{
sppcregister(session, cp); /* SPPC driver */
if (ppcavail) ppcregister(session, cp); /* PPC Toolbox */
}
void sppcregister(char session, cnr *cp)
{
static unsigned char smgrname[] = "GFTM1";
short i;
OSErr rc;
if (session == 0) { /* session manager registration */
smgrname[4] = '1';
sppc_sessname[4] = '1';
for (i=0; i < 8; i++) {
rc = SPPCRegister(smgrname, &smgrrefnum);
if (rc == noErr) {
smgr_sppc = 1;
break;
}
else {
smgrname[4]++;
sppc_sessname[4]++;
}
}
if (smgr_sppc) {
if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
if (sndMessage == 0) sndMessage = NewHandle((Size)128);
if ((rcvMessage == 0) || (sndMessage == 0)) {
apideregister(0, 0);
stoperr(apisalrt, 0);
}
}
else if (rc == dupFNErr) {
stoperr(apinalrt, 0); /* tell user about name problem */
}
}
else if (smgr_sppc) { /* session registration */
sppc_sessname[6] = '1';
for (i=0; i < 8; i++) {
rc = SPPCRegister(sppc_sessname, &(cp->sessrefnum));
if (rc == noErr) {
cp->sess_sppc = 1;
strcpy(cp->sppcname, sppc_sessname);
break;
}
else {
sppc_sessname[6]++;
}
}
if (!(cp->sess_sppc)) {
cp->sessrefnum = 0;
stoperr(apinalrt, cp); /* tell user about name problem */
}
}
}
void ppcregister(char session, cnr *cp)
{
static unsigned char smgrname[] = "\ptn3270 #1";
short i;
OSErr rc;
PPCOpenPBRec openpb;
PPCPortRec pr;
PPCParamBlockPtr ipb;
pascal void (*compproc)();
if (session == 0) { /* session manager registration */
smgrname[9] = '1';
ppcsessname[9] = '1';
for (i=0; i < 8; i++) {
memset(&pr, 0, sizeof(PPCPortRec));
memcpy(pr.name, smgrname, 10);
pr.portKindSelector = ppcByString;
memcpy(pr.u.portTypeStr, "\ptn3270 Session Manager", 23);
memset(&openpb, 0, sizeof(PPCOpenPBRec));
openpb.serviceType = ppcServiceRealTime;
openpb.portName = ≺
openpb.locationName = 0;
openpb.networkVisible = true;
rc = PPCOpen(&openpb, false);
if (rc == noErr) {
smgrppc = 1;
smgrpref = openpb.portRefNum;
break;
}
else {
smgrname[9]++;
ppcsessname[9]++;
}
}
if (smgrppc) {
if (rcvMessage == 0) rcvMessage = NewHandle((Size)128);
if (sndMessage == 0) sndMessage = NewHandle((Size)128);
/* issue Inform for our new port */
ipb = newparamblock();
if ((ipb == 0) || (rcvMessage == 0) || (sndMessage == 0)) {
stoperr(ppcopenalrt, 0);
ppcderegister(0, 0);
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = informproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
ipb->informParam.portRefNum = smgrpref;
ipb->informParam.autoAccept = false;
rc = PPCInform((PPCInformPBPtr)ipb, true);
if (rc != noErr) {
stoperr(ppcopenalrt, 0);
ppcderegister(0, 0);
}
}
else if (rc == -910) {
stoperr(ppcnamealrt, 0); /* tell user about name problem */
}
else {
stoperr(ppcopenalrt, 0); /* other problem */
}
}
else if (smgrppc) { /* session registration */
ppcsessname[19] = '1';
for (i=0; i < 8; i++) {
memset(&pr, 0, sizeof(PPCPortRec));
memcpy(pr.name, ppcsessname, 20);
pr.portKindSelector = ppcByString;
memcpy(pr.u.portTypeStr, "\ptn3270 Session", 15);
memset(&openpb, 0, sizeof(PPCOpenPBRec));
openpb.serviceType = ppcServiceRealTime;
openpb.portName = ≺
openpb.locationName = 0;
openpb.networkVisible = true;
rc = PPCOpen(&openpb, false);
if (rc == noErr) {
cp->sessppc = 1;
cp->sesspref = openpb.portRefNum;
p2cstr(ppcsessname);
strcpy(cp->ppcname, ppcsessname);
c2pstr(ppcsessname);
break;
}
else {
ppcsessname[19]++;
}
}
if (cp->sessppc) {
/* issue Inform for our new port */
ipb = newparamblock();
if (ipb == 0) {
stoperr(ppcnamealrt, cp);
ppcderegister(1, cp);
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = informproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
ipb->informParam.portRefNum = cp->sesspref;
ipb->informParam.autoAccept = false;
rc = PPCInform((PPCInformPBPtr)ipb, true);
if (rc != noErr) {
stoperr(ppcnamealrt, cp);
ppcderegister(1, cp);
}
}
else {
cp->sesspref = 0;
stoperr(ppcnamealrt, cp); /* tell user about name problem */
}
}
}
pascal void informproc(PPCParamBlockPtr pb)
{
OSErr rc;
pascal void (*compproc)();
clientinfo * cip;
PPCParamBlockPtr ipb;
short i;
cnr *cp;
char cpok;
if ((rc=pb->informParam.ioResult) != noErr) {
disposparamblock(pb);
return;
}
/* determine owner of this session */
cpok = false;
if (smgrppc && (pb->informParam.portRefNum == smgrpref)) {
cp = 0; /* check for session manager */
cpok = true;
}
else {
for (i=0; i < MAXSESSIONS; i++) {
cp = cplist[i]; /* check for session */
if (cp != 0) {
if (cp->sessppc && (pb->informParam.portRefNum == cp->sesspref)) {
cpok = true;
break;
}
}
}
}
cip = 0;
if (cpok) cip = newclientrec();
if (cip == 0) {
compproc = disposproc;
pb->rejectParam.ioCompletion = (PPCCompProcPtr)compproc;
rc = PPCReject((PPCRejectPBPtr)pb, true);
}
else {
cip->sessrefnum = pb->informParam.sessRefNum;
cip->userdata = pb->informParam.userData;
cip->servicetype = pb->informParam.serviceType;
cip->reqtype = pb->informParam.requestType;
cip->cp = cp;
compproc = accproc;
pb->acceptParam.ioCompletion = (PPCCompProcPtr)compproc;
rc = PPCAccept((PPCAcceptPBPtr)pb, true);
}
if (!cpok) return;
ipb = newparamblock();
if (ipb == 0) {
return;
}
memset(ipb, 0, sizeof(PPCParamBlockRec));
compproc = informproc;
ipb->informParam.ioCompletion = (PPCCompProcPtr)compproc;
if (cp == 0) {
ipb->informParam.portRefNum = smgrpref;
}
else {
ipb->informParam.portRefNum = cp->sesspref;
}
ipb->informParam.autoAccept = false;
rc = PPCInform((PPCInformPBPtr)ipb, true);
}
pascal void accproc(PPCParamBlockPtr pb)
{
datainfo *dip;
OSErr rc;
pascal void (*compproc)();
if ((rc=pb->acceptParam.ioResult) != noErr) {
deletesession(pb->acceptParam.sessRefNum);
disposparamblock(pb);
return;
}
dip = newdatablock();
if (dip == 0) {
compproc = disposproc;
pb->endParam.ioCompletion = (PPCCompProcPtr)compproc;
rc = PPCEnd((PPCEndPBPtr)pb, true);
deletesession(pb->acceptParam.sessRefNum);
return;
}
memset(dip, 0, sizeof(datainfo));
compproc = readproc;
pb->readParam.ioCompletion = (PPCCompProcPtr)compproc;
pb->readParam.bufferLength = 128;
pb->readParam.bufferPtr = dip->msg;
rc = PPCRead((PPCReadPBPtr)pb, true);
}
pascal void readproc(PPCParamBlockPtr pb)
{
datainfo *dip;
OSErr rc;
pascal void (*compproc)();
unsigned char *s;
if ((rc=pb->readParam.ioResult) != noErr) {
deletesession(pb->acceptParam.sessRefNum);
disposparamblock(pb);
return;
}
s = (unsigned char *)pb->readParam.bufferPtr;
s -= 22;
dip = (datainfo *)s;
dip->length = pb->readParam.actualLength;
dip->userdata = pb->readParam.userData;
dip->creator = pb->readParam.blockCreator;
dip->type = pb->readParam.blockType;
dip->sessrefnum = pb->readParam.sessRefNum;
dip->more = pb->readParam.more;
dip->incoming = 1;
dip = newdatablock();
if (dip == 0) {
compproc = disposproc;
pb->endParam.ioCompletion = (PPCCompProcPtr)compproc;
rc = PPCEnd((PPCEndPBPtr)pb, true);
deletesession(pb->acceptParam.sessRefNum);
return;
}
memset(dip, 0, sizeof(datainfo));
compproc = readproc;
pb->readParam.ioCompletion = (PPCCompProcPtr)compproc;
pb->readParam.bufferLength = 128;
pb->readParam.bufferPtr = dip->msg;
rc = PPCRead((PPCReadPBPtr)pb, true);
}
pascal void disposproc(PPCParamBlockPtr pb)
{
disposparamblock(pb);
}
void deletesession(long refnum)
{
clientrec *cp;
cp = (clientrec *)clientqueue.first;
while (cp != 0) {
if (cp->header.inuse) {
if (cp->client.sessrefnum == refnum) {
disposclientrec(&(cp->client));
return;
}
}
cp = (clientrec *)cp->header.next;
}
}
void apideregister(char session, cnr *cp) /* cancel API registration */
{
sppcderegister(session, cp); /* SPPC driver */
ppcderegister(session, cp); /* PPC Toolbox */
if (cp != 0) cp->apiwritenotify = 0;
}
void sppcderegister(char session, cnr *cp)
{
/* deregister session, if any */
if (cp != 0) {
if (cp->sess_sppc) {
SPPCDeRegister(cp->sessrefnum);
cp->sess_sppc = 0;
}
}
/* return if just session wanted */
if (session) return;
/* deregister session manager */
if (smgr_sppc) {
SPPCDeRegister(smgrrefnum);
smgr_sppc = 0;
}
}
void ppcderegister(char session, cnr *cp)
{
PPCClosePBRec closepb;
OSErr rc;
/* deregister session, if any */
if (cp != 0) {
if (cp->sessppc) {
memset(&closepb, 0, sizeof(PPCClosePBRec));
closepb.portRefNum = cp->sesspref;
rc = PPCClose(&closepb, false);
cp->sessppc = 0;
}
}
/* return if just session wanted */
if (session) return;
/* deregister session manager */
if (smgrppc) {
memset(&closepb, 0, sizeof(PPCClosePBRec));
closepb.portRefNum = smgrpref;
rc = PPCClose(&closepb, false);
smgrppc = 0;
}
}
void apinewmsg(void)
{
OSErr rc;
datarec *dp;
short i;
clientrec *cp;
char cpok;
if (smgr_sppc) {
apimsgkind = 1;
msgcp = 0; /* session manager */
rc = SPPCGet(smgrrefnum, &fromrefnum, 0, rcvMessage, &msgLength,
&msgId, &replyId);
if (rc == noErr) smgrmsg();
/* sessions */
for (i=0; i < MAXSESSIONS; i++) {
msgcp = cplist[i];
if (msgcp != 0) {
if (msgcp->sess_sppc) {
rc = SPPCGet(msgcp->sessrefnum, &fromrefnum, 0, rcvMessage,
&msgLength, &msgId, &replyId);
if (rc == noErr) sessmsg();
}
}
}
}
if (ppcavail) {
apimsgkind = 0;
dp = (datarec *)dataqueue.first;
while (dp != 0) {
if (dp->header.inuse) {
if (dp->data.incoming) {
ppcsref = dp->data.sessrefnum;
memcpy(*rcvMessage, dp->data.msg, dp->data.length);
msgLength = dp->data.length;
msgId = dp->data.userdata;
replyId = dp->data.creator;
cpok = false; /* find client record to get msgcp */
cp = (clientrec *)clientqueue.first;
while (cp != 0) {
if (cp->header.inuse) {
if (cp->client.sessrefnum == ppcsref) {
msgcp = cp->client.cp;
cpok = true;
break;
}
}
cp = (clientrec *)cp->header.next;
}
if (cpok) {
if (msgcp == 0) {
smgrmsg();
}
else {
sessmsg();
}
}
disposdatarec(&(dp->data));
}
}
dp = (datarec *)dp->header.next;
}
}
}
void smgrmsg(void)
{
short **msgh;
msgh = (short **)rcvMessage;
if (msgLength < 2) {
senderr(smgrrefnum, badRequestLength);
return;
}
switch (**msgh) {
case GetIdRequestType:
if (msgLength != sizeof(GetIdRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendid();
break;
case GetCapRequestType:
if (msgLength != sizeof(GetCapRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendcap();
break;
case GetVersRequestType:
if (msgLength != sizeof(GetVersRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendvers();
break;
case OpenRequestType:
if (msgLength != sizeof(OpenRequest)) {
senderr(smgrrefnum, badRequestLength);
return;
}
apiopensess();
break;
case GetConnStatusType:
if (msgLength != sizeof(GetConnStatus)) {
senderr(smgrrefnum, badRequestLength);
return;
}
sendconnstat();
break;
default:
senderr(smgrrefnum, badMessageType);
break;
}
}
void senderr(short myref, short code)
{
ErrorResponse er;
OSErr rc;
unsigned long respid;
er.msgtype = ErrorResponseType;
er.code = code;
memcpy(*sndMessage, &er, sizeof(ErrorResponse));
rc = apisend(myref, fromrefnum, msgId, sndMessage, sizeof(ErrorResponse),
&respid);
}
void sendcap(void)
{
GetCapResponse gcr;
OSErr rc;
unsigned long respid;
gcr.msgtype = GetCapResponseType;
getsesscount(&gcr.pendsessions, &gcr.currsessions);
gcr.maxsessions = MAXSESSIONS;
gcr.numbformats = 1;
gcr.sizeinfo[0].ptsize = 9;
gcr.sizeinfo[0].rows = rowmax9;
gcr.sizeinfo[0].cols = colmax9;
if ((rowmax12 >= 24) && (colmax12 >= 80)) {
gcr.numbformats = 2;
gcr.sizeinfo[1].ptsize = 12;
gcr.sizeinfo[1].rows = rowmax12;
gcr.sizeinfo[1].cols = colmax12;
}
memcpy(*sndMessage, &gcr, sizeof(GetCapResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetCapResponse), &respid);
}
void getsesscount(short *pend, short *curr)
{
short i;
cnr *cp;
(*pend) = (*curr) = 0;
for (i=0; i < MAXSESSIONS; i++) {
cp = cplist[i];
if (cp != 0) {
if (cp->sess_sppc || cp->sessppc) {
(*curr)++;
}
else {
(*pend)++;
}
}
}
}
void sendvers(void)
{
GetVersResponse gvr;
OSErr rc;
unsigned long respid;
Handle version;
Size vsize;
memset(&gvr, 0, sizeof(GetVersResponse));
gvr.msgtype = GetVersResponseType;
version = GetResource('vers', 1);
if (version != 0) {
vsize = GetHandleSize(version);
if (vsize > 120) vsize = 120;
memcpy(gvr.versdata, *version, vsize);
}
memcpy(*sndMessage, &gvr, vsize+8);
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, vsize+8, &respid);
}
void sendid(void)
{
GetIdResponse gir;
OSErr rc;
unsigned long respid;
unsigned char apName[256];
short apRefNum;
Handle apParam;
short namelen;
memset(&gir, 0, sizeof(GetIdResponse));
gir.msgtype = GetIdResponseType;
gir.signature = 'GFTM';
GetAppParms(apName, &apRefNum, &apParam);
p2cstr(apName);
gir.refnum = apRefNum;
namelen = strlen(apName);
namelen++;
if (namelen > 120) namelen = 120;
memcpy(gir.appname, apName, namelen);
memcpy(*sndMessage, &gir, namelen+12);
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage, namelen+12, &respid);
}
void apiopensess(void)
{
unsigned short len;
short pend, curr;
char fmtok;
OpenResponse or;
OSErr rc;
unsigned long respid;
/* check that a session can be opened now */
getsesscount(&pend, &curr);
if ((pend + curr) == MAXSESSIONS) {
memset(&or, 0, sizeof(OpenResponse));
or.msgtype = OpenResponseType;
or.code = openNoSessions;
memcpy(*sndMessage, &or, sizeof(OpenResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(OpenResponse), &respid);
return;
}
/* copy open session request data */
memcpy(&apiopenreq, *rcvMessage, sizeof(OpenRequest));
/* copy host name */
len = strlen(apiopenreq.hostname);
if (len > 255) len = 255;
memcpy(apihostname, apiopenreq.hostname, len+1);
apihostname[len] = 0;
apiopenreq.hostname = apihostname;
/* copy window name */
len = strlen(apiopenreq.windowname);
if (len > 255) len = 255;
memcpy(apiwindowname, apiopenreq.windowname, len+1);
apiwindowname[len] = 0;
apiopenreq.windowname = apiwindowname;
/* copy request message information */
apiopenrefnum = fromrefnum;
apiopenmsgid = msgId;
apiopenkind = apimsgkind;
apiopensref = ppcsref;
/* check the requested screen sizes are valid */
fmtok = 1;
if (apiopenreq.dfltsize.rows != 24) fmtok = 0;
if (apiopenreq.dfltsize.cols != 80) fmtok = 0;
if (apiopenreq.dfltsize.ptsize == 12) {
if (rowmax12 < 24) fmtok = 0;
if (colmax12 < 80) fmtok = 0;
}
else if (apiopenreq.dfltsize.ptsize != 9) fmtok = 0;
if (apiopenreq.altsize.rows < 24) fmtok = 0;
if (apiopenreq.altsize.cols < 80) fmtok = 0;
if (apiopenreq.altsize.ptsize == 9) {
if (rowmax9 < apiopenreq.altsize.rows) fmtok = 0;
if (colmax9 < apiopenreq.altsize.cols) fmtok = 0;
}
else if (apiopenreq.altsize.ptsize == 12) {
if (rowmax12 < apiopenreq.altsize.rows) fmtok = 0;
if (colmax12 < apiopenreq.altsize.cols) fmtok = 0;
}
else fmtok = 0;
if (fmtok == 0) {
apiopenerr(openFormatErr, 0);
return;
}
newlogin(1, 0, 0, 0, 0); /* new login with apiopen true */
}
void apiopenerr(short code, cnr *cp)
{
if (cp != 0) cp->apiopen = 0;
apiopenresp(code, cp);
}
void apiopenresp(short code, cnr *cp)
{
OpenResponse or;
OSErr rc;
unsigned long respid;
short len;
memset(&or, 0, sizeof(OpenResponse));
or.msgtype = OpenResponseType;
or.code = code;
if ((code == open3270Mode) || (code == openLineMode)) {
if (smgr_sppc) {
or.sppcrefnum = cp->sessrefnum;
if (cp->sppcname != 0) {
len = strlen(cp->sppcname);
if (len > 8) len = 8;
memcpy(or.sppcname, cp->sppcname, len+1);
}
}
if (smgrppc) {
or.ppcportnum = cp->sesspref;
if (cp->ppcname != 0) {
len = strlen(cp->ppcname);
if (len > 20) len = 20;
memcpy(or.ppcname, cp->ppcname, len+1);
}
}
}
memcpy(*sndMessage, &or, sizeof(OpenResponse));
/* restore message information */
if (cp != 0) {
fromrefnum = cp->apiopenrefnum;
msgId = cp->apiopenmsgid;
apimsgkind = cp->apiopenkind;
ppcsref = cp->apiopensref;
}
else {
fromrefnum = apiopenrefnum;
msgId = apiopenmsgid;
apimsgkind = apiopenkind;
ppcsref = apiopensref;
}
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(OpenResponse), &respid);
if (cp != 0) cp->apiopenpend = 0;
}
void sendconnstat(void)
{
GetConnResponse gcr;
unsigned long openid;
OSErr rc;
unsigned long respid;
openid = (*((GetConnStatus **)rcvMessage))->openid;
memset(&gcr, 0, sizeof(GetConnResponse));
gcr.msgtype = GetConnResponseType;
gcr.openid = openid;
gcr.statuscode = getconnstat(openid);
if (gcr.statuscode == openBadId) gcr.openid = 0;
memcpy(*sndMessage, &gcr, sizeof(GetConnResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetConnResponse), &respid);
}
short getconnstat(unsigned long openid)
{
short i;
cnr *cp;
char cpok;
cpok = 0;
for (i=0; i < MAXSESSIONS; i++) {
cp = cplist[i];
if (cp != 0) {
cpok = cp->apiopen && (openid == cp->apiopenmsgid) &&
(cp->apiopenkind == apimsgkind);
if (cpok) break;
}
}
if (!cpok) return(openBadId);
if (cp->apiopenpend == 0) {
if (cp->logon) return(open3270Mode);
else return(openLineMode);
}
if (cp->serflg) return(openConnPending);
switch(cp->connstate) {
case 2:
return(openResPending);
break;
case 3:
return(openConnPending);
break;
case 4:
return(openNegOptions);
break;
default:
return(noError);
break;
}
}
OSErr apisend(short myRefNum, short toRefNum,
unsigned long replyId, Handle theMessage,
unsigned short msgLength, unsigned long *msgId)
{
PPCParamBlockPtr wbp;
datainfo *dp;
pascal void (*compproc)();
pascal void writeproc();
if (apimsgkind == 1) {
return(SPPCSend(myRefNum, toRefNum, replyId, theMessage,
msgLength, msgId));
}
else {
wbp = newparamblock();
if (wbp == 0) {
return(mFulErr);
}
dp = newdatablock();
if (dp == 0) {
disposparamblock(wbp);
return(mFulErr);
}
memset(wbp, 0, sizeof(PPCParamBlockRec));
compproc = writeproc;
wbp->writeParam.ioCompletion = (PPCCompProcPtr)compproc;
wbp->writeParam.sessRefNum = ppcsref;
wbp->writeParam.bufferLength = msgLength;
wbp->writeParam.bufferPtr = dp->msg;
apimsgid++;
wbp->writeParam.userData = apimsgid;
wbp->writeParam.blockCreator = replyId;
memset(dp, 0, sizeof(datainfo));
memcpy(dp->msg, *theMessage, msgLength);
return(PPCWrite((PPCWritePBPtr)wbp, true));
}
}
pascal void writeproc(PPCParamBlockPtr pb)
{
unsigned char *s;
datainfo * d;
s = (unsigned char *)pb->writeParam.bufferPtr;
s -= 24;
d = (datainfo *)s;
disposdatarec(d);
disposparamblock(pb);
}
void sessmsg(void)
{
short **msgh;
msgh = (short **)rcvMessage;
if (msgLength < 2) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
switch (**msgh) {
case GetCharRequestType:
if (msgLength != sizeof(GetCharRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
sendchar();
break;
case CloseRequestType:
if (msgLength != sizeof(CloseRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
sessclose(msgcp);
break;
case CloseNotifyRequestType:
if (msgLength != sizeof(CloseNotifyRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
closenotify();
break;
case GetBuffersRequestType:
if (msgLength != sizeof(GetBuffersRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
getbuffers();
break;
case WriteNotifyRequestType:
if (msgLength != sizeof(WriteNotifyRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
writenotify();
break;
case SendDataRequestType:
if (msgLength != sizeof(SendDataRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
senddatareq();
break;
case SendLocalRequestType:
if (msgLength != sizeof(SendLocalRequest)) {
senderr(msgcp->sessrefnum, badRequestLength);
return;
}
sendlocal();
break;
default:
senderr(msgcp->sessrefnum, badMessageType);
break;
}
}
void sendchar(void)
{
GetCharResponse gcr;
OSErr rc;
unsigned long respid;
unsigned char *dest;
short len;
memset(&gcr, 0, sizeof(GetCharResponse));
gcr.msgtype = GetCharResponseType;
dest = (*((GetCharRequest **)rcvMessage))->hostname;
if (dest != 0) {
len = strlen(msgcp->connhostname);
if (len > 255) len = 255;
memcpy(dest, msgcp->connhostname, len+1);
}
dest = (*((GetCharRequest **)rcvMessage))->windowname;
if (dest != 0) {
len = strlen(msgcp->cswtitle);
if (len > 127) len = 127;
memcpy(dest, msgcp->cswtitle, len+1);
}
gcr.dfltsize.ptsize = msgcp->cs.dfltptsize;
gcr.dfltsize.rows = 24;
gcr.dfltsize.cols = 80;
gcr.altsize.ptsize = msgcp->cs.altptsize;
gcr.altsize.rows = msgcp->cs.altrows;
gcr.altsize.cols = msgcp->cs.altcols;
gcr.linemode = (msgcp->logon == 0);
gcr.hide = msgcp->apihide;
gcr.nowsf = msgcp->cs.ext3270 == 0;
gcr.noalert = msgcp->apinoalert;
memcpy(*sndMessage, &gcr, sizeof(GetCharResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetCharResponse), &respid);
}
void sessclose(cnr *cp)
{
CloseResponse cr;
OSErr rc;
unsigned long respid;
memset(&cr, 0, sizeof(CloseResponse));
cr.msgtype = CloseResponseType;
cr.code = noError;
memcpy(*sndMessage, &cr, sizeof(CloseResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(CloseResponse), &respid);
closeresponse(closeAPI, cp);
if (cp->serflg) serlgout(0, cp);
else if (cp->tcpflg) tcplgout(0, cp);
else salgout(0, cp);
}
void closenotify(void)
{
CloseNotifyResponse cnr;
OSErr rc;
unsigned long respid;
memset(&cnr, 0, sizeof(CloseNotifyResponse));
cnr.msgtype = CloseNotifyResponseType;
if ((*((CloseNotifyRequest **)rcvMessage))->notifyflag) {
if (msgcp->apiclosenotify) {
cnr.code = closeNotifyActive;
}
else {
cnr.code = noError;
msgcp->apiclosenotify = 1;
/* copy request message information */
msgcp->apicloserefnum = fromrefnum;
msgcp->apiclosemsgid = msgId;
msgcp->apiclosekind = apimsgkind;
msgcp->apiclosesref = ppcsref;
}
}
else {
msgcp->apiclosenotify = 0;
cnr.code = noError;
}
memcpy(*sndMessage, &cnr, sizeof(CloseNotifyResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(CloseNotifyResponse), &respid);
}
void closeresponse(short code, cnr *cp)
{
CloseEventResponse cer;
OSErr rc;
unsigned long respid;
if (!cp->apiclosenotify) return;
memset(&cer, 0, sizeof(CloseEventResponse));
cer.msgtype = CloseEventResponseType;
cer.code = code;
if (smgr_sppc) {
cer.sppcrefnum = cp->sessrefnum;
}
if (smgrppc) {
cer.ppcportnum = cp->sesspref;
}
memcpy(*sndMessage, &cer, sizeof(CloseEventResponse));
/* restore message information */
fromrefnum = cp->apicloserefnum;
msgId = cp->apiclosemsgid;
apimsgkind = cp->apiclosekind;
ppcsref = cp->apiclosesref;
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(CloseEventResponse), &respid);
cp->apiclosenotify = 0;
}
void getbuffers(void)
{
GetBuffersResponse gbr;
OSErr rc;
unsigned long respid;
memset(&gbr, 0, sizeof(GetBuffersResponse));
gbr.msgtype = GetBuffersResponseType;
gbr.databuff = msgcp->chrbuff;
gbr.attrbuff = msgcp->atrbuff;
gbr.kblock = &(msgcp->kblock);
gbr.kblcode = &(msgcp->kblcode);
gbr.curadr = (unsigned short *)&(msgcp->curadr);
memcpy(*sndMessage, &gbr, sizeof(GetBuffersResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(GetBuffersResponse), &respid);
}
void writenotify(void)
{
WriteNotifyResponse wnr;
OSErr rc;
unsigned long respid;
memset(&wnr, 0, sizeof(WriteNotifyResponse));
wnr.msgtype = WriteNotifyResponseType;
if ((*((WriteNotifyRequest **)rcvMessage))->notifyflag) {
if (msgcp->apiwritenotify) {
wnr.code = writeNotifyActive;
}
else {
wnr.code = noError;
msgcp->apiwritenotify = 1;
/* copy request message information */
msgcp->apiwriterefnum = fromrefnum;
msgcp->apiwritemsgid = msgId;
msgcp->apiwritekind = apimsgkind;
msgcp->apiwritesref = ppcsref;
}
}
else {
msgcp->apiwritenotify = 0;
wnr.code = noError;
}
memcpy(*sndMessage, &wnr, sizeof(WriteNotifyResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(WriteNotifyResponse), &respid);
}
void writeresponse(unsigned char ccwop, cnr *cp)
{
WriteEventResponse wer;
OSErr rc;
unsigned long respid;
if (!(cp->apiwritenotify)) return;
memset(&wer, 0, sizeof(WriteEventResponse));
wer.msgtype = WriteEventResponseType;
wer.ccwop = ccwop;
if (smgr_sppc) {
wer.sppcrefnum = cp->sessrefnum;
}
if (smgrppc) {
wer.ppcportnum = cp->sesspref;
}
memcpy(*sndMessage, &wer, sizeof(WriteEventResponse));
/* restore message information */
fromrefnum = cp->apiwriterefnum;
msgId = cp->apiwritemsgid;
apimsgkind = cp->apiwritekind;
ppcsref = cp->apiwritesref;
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(WriteEventResponse), &respid);
}
void senddatareq(void)
{
SendDataResponse sdr;
OSErr rc;
unsigned long respid;
unsigned short caddr;
short length;
unsigned char *s;
unsigned char aidcode;
short i;
char geflag;
memset(&sdr, 0, sizeof(SendDataResponse));
sdr.msgtype = SendDataResponseType;
length = (*((SendDataRequest **)rcvMessage))->length;
s = (*((SendDataRequest **)rcvMessage))->data;
if ((msgcp->connstate == 1) && msgcp->serflg) { /* serial connection mode */
if (length > 0) {
for (i=0; i < length; i++) {
apisendser(s[i], msgcp);
sdr.count++;
}
}
}
else if (msgcp->tcpflg && (msgcp->connstate == 4)) {
if (length > 0) { /* 3270 line mode */
if (msgcp->servermode) {
putsrv(s, length, 1, msgcp);
}
else {
if (!(msgcp->hisopts[TELOPT_ECHO])) {
putscr(s, length, 0, msgcp);
}
tcpwrite(s, length, msgcp);
}
sdr.count = length;
}
}
else { /* 3270 session */
caddr = (*((SendDataRequest **)rcvMessage))->curadr;
aidcode = (*((SendDataRequest **)rcvMessage))->aidcode;
/* check for fatal errors */
if (msgcp->kblock) {
sdr.code = sendLocked;
}
else if ((caddr != 0xffff) && (caddr > msgcp->maxoff)) {
sdr.code = sendBadAddress;
}
if (sdr.code == noError) {
/* set cursor address */
if (caddr != 0xffff) {
msgcp->curadr = caddr;
newcur(msgcp);
}
/* store data */
if (length > 0) {
geflag = 0;
msgcp->apikberr = 0;
for (i=0; i < length; i++) {
if (s[i] == 0x08) {
geflag = 1;
}
else {
datakey(s[i], geflag, 0, msgcp);
geflag = 0;
if (msgcp->apikberr) {
sdr.code = msgcp->apikberr;
break;
}
else {
sdr.count++;
}
}
}
}
/* send AID */
if ((aidcode != 0) && (sdr.code == noError)) {
msgcp->apikberr = 0;
attnkey(aidcode, 0, msgcp);
sdr.code = msgcp->apikberr;
}
}
}
sdr.curadr = msgcp->curadr;
memcpy(*sndMessage, &sdr, sizeof(SendDataResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(SendDataResponse), &respid);
}
void apisendser(unsigned char c, cnr *cp)
{
if (c == 0x12) {
cp->serverflags = 0x01;
srvswitch(cp);
}
else {
if (cp->servermode) {
putsrv(&c, 1, 1, cp);
}
else {
serout(c);
}
}
}
void sendlocal(void)
{
SendLocalResponse slr;
OSErr rc;
unsigned long respid;
short length;
unsigned char *s;
short i;
memset(&slr, 0, sizeof(SendLocalResponse));
slr.msgtype = SendLocalResponseType;
length = (*((SendLocalRequest **)rcvMessage))->length;
s = (*((SendLocalRequest **)rcvMessage))->data;
if (length > 0) {
/* check for fatal errors */
if (msgcp->kblock) {
if (s[0] != 13) {
slr.code = sendLocked;
}
}
if (slr.code == noError) {
/* execute operations */
msgcp->apikberr = 0;
for (i=0; i < length; i++) {
funckey(s[i], 0, msgcp);
if (msgcp->apikberr) {
slr.code = msgcp->apikberr;
break;
}
else {
slr.count++;
}
}
}
}
slr.curadr = msgcp->curadr;
memcpy(*sndMessage, &slr, sizeof(SendLocalResponse));
rc = apisend(smgrrefnum, fromrefnum, msgId, sndMessage,
sizeof(SendLocalResponse), &respid);
}